using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using System.Web;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

namespace NoASP
{
    public class Startup
    {
        QueryString ParseFrom(HttpContext context, Dictionary<string, string> package)
        {
            QueryString queryString;

            if (context.Request.Method == "POST")
            {
                Stream reqStream = context.Request.Body;
                using (StreamReader reader = new StreamReader(reqStream))
                {
                    string content = reader.ReadToEnd();
                    if (content[0] != '?')
                    {
                        content = "?" + content;
                    }
                    queryString = QueryString.FromUriComponent(content);
                }
            }
            else
            {
                string content = context.Request.QueryString.Value;
                queryString = QueryString.FromUriComponent(content);
            }

            if (package != null)
            {
                NameValueCollection contentMap = HttpUtility.ParseQueryString(queryString.ToUriComponent());
                foreach (string key in contentMap.AllKeys)
                {
                    package.Add(key, contentMap[key]);
                }
            }

            return queryString;
        }

        string OneHtmlTemplate()
        {
            string html = @"
                <html>
                    <body>
                        <form action='action.html' method='post'>
                            <div id='id_page_context'>
                            </div>
                        </form>
                    </body>
                </html>
            ";

            return html;
        }

        public void Configure(IApplicationBuilder application)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            application.UseStaticFiles();
            application.Run(context =>
            {
                // request path value as app path
                string appPath = context.Request.Path.Value;

                if (appPath.Contains(".html") == false)
                {
                    return context.Response.WriteAsync(string.Empty);
                }

                // ParseFrom is to parse the html form data to the package
                Dictionary<string, string> package = new Dictionary<string, string>();
                ParseFrom(context, package);

                if (appPath == "/index.html")
                {
                    // how to append html controls by xml operations
                    //////////////////////////////////////////////////////////

                    // new a xml document for xml operations
                    // and using Goto to get the node of id_page_context
                    xmlDoc doc = new xmlDoc();
                    doc.LoadXmlContent(OneHtmlTemplate());
                    doc.Goto("id_page_context");

                    // here the new node's content must have one root node
                    // so I add a <div> node as the root node to include all html content
                    doc.Begin(@"
                        <div>
                            First Name: <input type='text' name='first_name'>  <br>
                            Last Name: <input type='text' name='last_name'>
                            <input type='submit' value='Submit'>
                        </div>
                    ");
                    // End is just go back to parent xml node
                    doc.End();

                    // you can use this method to replace ASP MVC
                    // it uses the xml to handle html assembly, because html is a special xml
                    //////////////////////////////////////////////////////////

                    // GetString is to get a xml document content back to client
                    return context.Response.WriteAsync(doc.GetString());
                }
                else if (appPath == "/action.html")
                {
                    // get inputs and handle the post
                    if (package.ContainsKey("first_name") && package.ContainsKey("last_name"))
                    {
                        string firstName = package["first_name"];
                        string lastName = package["last_name"];
                        return context.Response.WriteAsync("my name is : " + firstName + lastName);
                    }
                }

                return context.Response.WriteAsync(string.Empty);
            });
        }
    }
}

